/*
 * Copyright (c) 2024 Huawei Technologies Co.,Ltd.
 *
 * openGauss is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *
 * http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 * -------------------------------------------------------------------------
 *
 * htap_debug.h
 * Debug utilities for HTAP module.
 *
 * IDENTIFICATION
 * src/include/storage/htap/htap_debug.h
 *
 * -------------------------------------------------------------------------
 */

#ifndef HTAP_DEBUG_H
#define HTAP_DEBUG_H

#include <cstdarg>
#include "debug_utils.h"
#include "htap_logger.h"

#ifdef MOT_DEBUG
#define HTAP_DEBUG
#endif

// unlike assert (which is defined if NDEBUG is not defined), we define MOT_ASSERT on explicit debug mode
#ifdef HTAP_DEBUG
#define HTAP_ASSERT assert
#else
#define HTAP_ASSERT(invariant)
#endif

/* * @define The maximum number of frames allowed in a call stack. */
#define HTAP_CALL_STACK_MAX_FRAMES MOT_CALL_STACK_MAX_FRAMES

/**
 * @define Specifies that mangled frame names should be demangled (triggers execution of c++filt sub-process for each
 * frame in the stack trace).
 */
#define HTAP_CALL_STACK_DEMANGLE MOT_CALL_STACK_DEMANGLE

/**
 * @define Specifies that frame addresses should be converted to file and line number (triggers execution of addr2line
 * sub-process for each frame in the stack trace).
 */
#define HTAP_CALL_STACK_FILE_LINE MOT_CALL_STACK_FILE_LINE

/* * @define Specifies that full module path of each frame should be printed. */
#define HTAP_CALL_STACK_MODULE MOT_CALL_STACK_MODULE

/* * @define Specifies that frame addresses should be printed. */
#define HTAP_CALL_STACK_ADDRESS MOT_CALL_STACK_ADDRESS

/* * #define Slim call stack options (just module and address for quick printing). */
#define HTAP_CALL_STACK_SLIM MOT_CALL_STACK_SLIM

/* * #define Normal call stack options (includes name demangling). */
#define HTAP_CALL_STACK_NORMAL MOT_CALL_STACK_NORMAL

/* * #define Full call stack options (very slow). */
#define HTAP_CALL_STACK_FULL MOT_CALL_STACK_FULL

/* * @define Maximum number of character in a call stack frame string member. */
#define HTAP_CALL_STACK_MAX_NAME MOT_CALL_STACK_MAX_NAME

namespace htap {
using CallStackFrame = MOT::CallStackFrame;

/**
 * @brief A global abort function for all fatal errors. This function is supposed to analyze the faulting address
 * (if any) and dump an analysis report, as well as a full map report.
 * @param faultAddress The faulting address
 */
inline void HTAPAbort(void *faultAddress = nullptr)
{
    MOT::MOTAbort(faultAddress);
}

/**
 * @brief Debug helper for printing current stack trace (can be used later with addr2line). This is the most primitive
 * way to dump call stack to log, without any formatting.
 */
inline void HTAPDumpCallStack()
{
    MOT::MOTDumpCallStack();
}

/**
 * @brief Retrieves the current call stack. No more than @ref MOT_CALL_STACK_MAX_FRAMES will be retrieved.
 * @param[out] resolvedFrames The array of call stack frames to be resolved.
 * @param frameCount The number of frames in the frame array.
 * @param opts Frame parsing options.
 * @return The number of resolved frames.
 */
inline int HTAPGetCallStack(CallStackFrame *resolvedFrames, uint32_t frameCount, int opts)
{
    return MOT::MOTGetCallStack(resolvedFrames, frameCount, opts);
}

/**
 * @brief Prints a message along with a call stack.
 * @param logLevel The message log level.
 * @param logger The logger name.
 * @param opts Call stack printing options.
 * @param format The message format to print.
 * @param args Any additional parameters required for the format message.
 */
inline void HTAPPrintCallStackImplV(LogLevel logLevel, const char *logger, int opts, const char *format, va_list args)
{
    MOT::MOTPrintCallStackImplV(logLevel, logger, opts, format, args);
}

/**
 * @brief Prints a message along with a call stack.
 * @param logLevel The message log level.
 * @param logger The logger name.
 * @param opts Call stack printing options.
 * @param format The message format to print.
 * @param ... Any additional parameters required for the format message.
 */
inline void HTAPPrintCallStackImpl(LogLevel logLevel, const char *logger, int opts, const char *format, ...)
{
    va_list args;
    va_start(args, format);

    HTAPPrintCallStackImplV(logLevel, logger, opts, format, args);

    va_end(args);
}
} // namespace htap

#endif /* HTAP_DEBUG_H */
